﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Linq;
using System.Web.UI;
using NativeCode.Web.Controls.Data;
using NativeCode.Web.Controls.Renderers;
using NativeCode.Web.Extensions;

namespace NativeCode.Web.Controls
{
	public enum CheckBoxSelectorType
	{
		Default = 0,
		CheckBoxList = 1,
		CheckBoxSelector = 2,
	}

	[ControlBuilder(typeof (GenericControlBuilder))]
	public class CheckBoxSelector : CheckBoxSelector<object>
	{
	}

	public class CheckBoxSelector<TDataItem> : GenericDataBoundControl<TDataItem, CheckBoxSelectorQuery>, IPostBackDataHandler
		where TDataItem : new()
	{
		private readonly CheckBoxSelectorRendererOptions _checkBoxRendererOptions = new CheckBoxSelectorRendererOptions();
		private List<CheckBoxSelectorItem> _checkBoxSelectorItems = new List<CheckBoxSelectorItem>();

		#region Events

		public event EventHandler<CheckBoxSelectorEventArgs<TDataItem>> ItemDataBound;

		public void InvokeItemDataBound(CheckBoxSelectorEventArgs<TDataItem> e)
		{
			EventHandler<CheckBoxSelectorEventArgs<TDataItem>> handler = ItemDataBound;
			if (handler != null)
			{
				handler(this, e);
			}
		}

		#endregion

		#region Properties

		[Browsable(false)]
		public IEnumerable<CheckBoxSelectorItem> CheckBoxSelectorItems
		{
			get { return _checkBoxSelectorItems; }
			set { _checkBoxSelectorItems = new List<CheckBoxSelectorItem>(value); }
		}

		[Browsable(true)]
		public string CheckBoxLabelField { get; set; }

		[Browsable(true)]
		public string CheckBoxToolTipField { get; set; }

		[Browsable(true)]
		public string CheckBoxValueField { get; set; }

		[Browsable(true)]
		public CheckBoxSelectorType CheckBoxSelectorType
		{
			get { return _checkBoxRendererOptions.CheckBoxSelectorType; }
			set { _checkBoxRendererOptions.CheckBoxSelectorType = value; }
		}

		[Browsable(true)]
		public LabelPosition LabelPosition
		{
			get { return _checkBoxRendererOptions.LabelPosition; }
			set { _checkBoxRendererOptions.LabelPosition = value; }
		}

		#endregion

		#region Overrides of GenericDataBoundControl<TDataItem,CheckBoxSelectorQuery>

		protected override CheckBoxSelectorQuery CreateQueryType()
		{
			return new CheckBoxSelectorQuery();
		}

		protected override void ValidateDataSource(object dataSource)
		{
			if (ItemDataBound == null && string.IsNullOrEmpty(CheckBoxLabelField) && string.IsNullOrEmpty(CheckBoxValueField))
			{
				throw new InvalidOperationException("You are not handling the ItemDataBound event and did not assign a CheckBoxLabelField and CheckBoxValueField value.");
			}

			base.ValidateDataSource(dataSource);
		}

		public override void PerformDataBinding(IQueryable<TDataItem> results, int resultsCount)
		{
			ValidateDataSource(results);

			for (int i = 0; i < resultsCount; i++ )
			{
				TDataItem dataItem  = results.ElementAt(i);
				CheckBoxSelectorItem checkBoxSelectorItem = new CheckBoxSelectorItem();

				if (!string.IsNullOrEmpty(CheckBoxLabelField))
				{
					checkBoxSelectorItem.Label = DataBinderHelper.GetPropertyValue(dataItem, CheckBoxLabelField);
				}

				if (!string.IsNullOrEmpty(CheckBoxValueField))
				{
					checkBoxSelectorItem.Value = DataBinderHelper.GetPropertyValue(dataItem, CheckBoxValueField);
				}

				checkBoxSelectorItem.ControlId = string.Format("{0}_{1}_{2}", ClientID, "CheckBox", i);
				_checkBoxSelectorItems.Add(checkBoxSelectorItem);
				InvokeItemDataBound(new CheckBoxSelectorEventArgs<TDataItem>(dataItem));
			}

			ViewState.Write(UniqueID, CheckBoxSelectorItems);
		}

		protected override void CreateChildControls()
		{
			IEnumerable<CheckBoxSelectorItem> checkBoxSelectorItems = ViewState.Read<IEnumerable<CheckBoxSelectorItem>>(UniqueID);
			if (checkBoxSelectorItems != null)
			{
				CheckBoxSelectorItems = checkBoxSelectorItems;
			}

			ChildControlsCreated = true;
		}

		protected override void Render(HtmlTextWriter writer)
		{
			CheckBoxSelectorRenderer<TDataItem> renderer = new CheckBoxSelectorRenderer<TDataItem>(writer);
			renderer.RenderCheckBoxSelectorControl(this, _checkBoxRendererOptions);
		}

		#endregion

		#region Implementation of IPostBackDataHandler

		public bool LoadPostData(string postDataKey, NameValueCollection postCollection)
		{
			return true;
		}

		public void RaisePostDataChangedEvent()
		{
		}

		#endregion
	}
}